﻿using System;
using System.Collections.Generic;
using Amazon.SimpleDB.Model;
using CsiroCloudAggregator.User.Object;
using ICommonLibrary;
using ICommonLibrary.Aws;
using ICommonLibrary.Collection;
using ICommonLibrary.Service;
using ICommonLibrary.Service.Error;

namespace CsiroCloudAggregator.User {

    public class AwsUserAccountService : ServiceBase, IAwsUserAccountService {
        
        public AmazonSimpleDbService SimpleDbService { get; set; }
        public string DomainName { get; set; }
        
        protected override void OnInit() {
            Asserts.NotNull(SimpleDbService, "AmazonSimpleDB Can not be Null");
            Asserts.NotNull(DomainName, "DomainName Can not be Null");
        }

        protected override void OnDestroy() {
        }

        protected override void OnStart() {
        }

        protected override void OnStop() {
        }

        public AwsAuthenticationResponse Authenticate(AwsAuthenticationRequest request) {
            if (string.IsNullOrEmpty(request.Email) ||
                 string.IsNullOrEmpty(request.SecurePassword)) {
                return AwsAuthenticationResponse.CreateFailResponse();
            }

            String query = string.Format(
                "Select * From `{0}` Where itemName() = '{1}' and `{2}` = '{3}'",
                DomainName,
                GetItemName(request.Email),
                AwsUserAccountAttributes.SecPassword, request.SecurePassword
            );

            var response = SimpleDbService.Select( new SelectRequest().WithSelectExpression(query));

            if (response.IsSetSelectResult()) {
                List<Item> items = response.SelectResult.Item;
                return CollectionUtil.IsEmpty(items) ?
                        AwsAuthenticationResponse.CreateFailResponse() :
                        AwsAuthenticationResponse.CreateSuccessfulResponse(items[0]);
            }

            return AwsAuthenticationResponse.CreateFailResponse();
        }

        public AwsUserAccount GetAwsUserAccount(string email) {
            String query = string.Format(
                "Select * From `{0}` Where itemName() = '{1}'",
                DomainName, GetItemName(email)
            );

            SelectResponse response = SimpleDbService.Select(
                new SelectRequest().WithSelectExpression(query));

            if (response.IsSetSelectResult()) {
                SelectResult result = response.SelectResult;
                return result.Item.Count == 0 ? null : AwsUserAccountHelper.CreateAwsUserAccount(result.Item[0]);
            }
            return null;
        }

        public bool AddAwsUserAccount(AddAwsUserAccountRequest request) {
            var userAccount = GetAwsUserAccount(request.Email);
            if (userAccount != null) {
                throw new InvalidRequestException("This user account already exists.");
            }
            PutAttributesRequest dbRequest = new PutAttributesRequest().WithDomainName(DomainName).WithItemName(GetItemName(request.Email));
            dbRequest.Attribute.AddRange(request.Attributes);
            SimpleDbService.PutAttributes(dbRequest);
            return true;
        }

        public GetAwsUserAccountsResponse GetAllAwsUserAccounts() {
            var query = string.Format(
              "Select * From `{0}`",
              DomainName
            );
            var dbResponse = SimpleDbService.Select(
                new SelectRequest ().WithSelectExpression(query));
            return new GetAwsUserAccountsResponse(dbResponse);
        }

        public DeleteAttributesResponse DeleteUserAccount(string email) {
            var request = new DeleteAttributesRequest().WithDomainName(DomainName).WithItemName(GetItemName(email));
            return SimpleDbService.DeleteAttributes(request);
        }

      

        private static string GetItemName(string email) {
            return email.ToLower();
        }
    }
}